package com.fand.persistent.support;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.util.CollectionUtils;

import com.fand.router.support.RouterKeySupport;
import com.fand.template.utils.FreemarkerTemplateUtils;

/**
 * 路由键名
 * 
 * @author yaoHT
 */
public class DefaultRouterKeySupport implements RouterKeySupport {
	private static final String CACHE_NAME = "routerNamedParameterJdbcTemplateChche";
	
	private RouterKeyConfig defaultRouterKeyConfig;
	
	/**
	 * 路由键名配置
	 */
	private Map<String, RouterKeyConfig> routerKeyConfigs;
	
	public RouterKeyConfig getDefaultRouterKeyConfig() {
		return this.defaultRouterKeyConfig;
	}
	
	@Override
	@Cacheable(value = DefaultRouterKeySupport.CACHE_NAME, key = "#key")
	public String getGroupId(String key) {
		return null;
	}
	
	private String getKey(final List<RouterKeyConfig> routerKeyConfigs, final String value, Object model) {
		if (CollectionUtils.isEmpty(routerKeyConfigs)) { return null; }
		
		for (final RouterKeyConfig routerKeyConfig : routerKeyConfigs) {
			if (!StringUtils.startsWith(value, routerKeyConfig.getPrefix())) {
				continue;
			}
			
			final String key = this.getKey(routerKeyConfig.getChilds(), value, model);
			
			if (StringUtils.isNotBlank(key)) { return key; }
			
			String expressionKey = null;
			
			if (org.apache.commons.lang3.StringUtils.isNotBlank(routerKeyConfig.getExpression())) {
				expressionKey = FreemarkerTemplateUtils.processString(routerKeyConfig.getExpression(), model);
			}
			
			return this.getKey(routerKeyConfig, expressionKey);
		}
		
		return null;
	}
	
	private String getKey(RouterKeyConfig routerKeyConfig, String expressionKey) {
		if (CollectionUtils.isEmpty(routerKeyConfig.getKeys())) { return com.fand.utils.StringUtils
		        .defaultIfBlank(routerKeyConfig.getTargetKey(), routerKeyConfig.getDefaultKey()); }
		
		if (!routerKeyConfig.getKeys().contains(routerKeyConfig.getDefaultKey())) {
			routerKeyConfig.setDefaultKey(routerKeyConfig.getKeys().get(0));
		}
		
		if (!routerKeyConfig.getKeys().contains(routerKeyConfig.getTargetKey())) {
			routerKeyConfig.setTargetKey(routerKeyConfig.getDefaultKey());
		}
		
		expressionKey = StringUtils.trim(expressionKey);
		
		if (routerKeyConfig.getKeys().contains(expressionKey)) { return expressionKey; }
		
		return com.fand.utils.StringUtils.defaultIfBlank(routerKeyConfig.getTargetKey(),
		        routerKeyConfig.getDefaultKey());
	}
	
	private String getKey(final RouterKeyConfig routerKeyConfig, final String value, Object model) {
		if (routerKeyConfig == null) { return null; }
		
		final String key = this.getKey(routerKeyConfig.getChilds(), value, model);
		
		if (StringUtils.isNotBlank(key)) { return key; }
		
		String expressionKey = null;
		
		if (org.apache.commons.lang3.StringUtils.isNotBlank(routerKeyConfig.getExpression())) {
			expressionKey = FreemarkerTemplateUtils.processString(routerKeyConfig.getExpression(), model);
		}
		
		return this.getKey(routerKeyConfig, expressionKey);
	}
	
	@Override
	@Cacheable(value = DefaultRouterKeySupport.CACHE_NAME)
	public String getKey(final String groupId, final String value, Object model) {
		if (StringUtils.isBlank(value)) { return this.getKey(this.defaultRouterKeyConfig, null); }
		
		if (StringUtils.isBlank(groupId)) { return this.getKey(this.defaultRouterKeyConfig, null); }
		
		if (CollectionUtils.isEmpty(this.routerKeyConfigs)) { return this.getKey(this.defaultRouterKeyConfig,
		        null); }
		
		if (this.routerKeyConfigs.containsKey(groupId)) {
			final RouterKeyConfig routerKeyConfig = this.routerKeyConfigs.get(groupId);
			
			final String key = this.getKey(routerKeyConfig, value, model);
			
			if (StringUtils.isNotBlank(key)) { return key; }
		}
		
		return this.getKey(this.defaultRouterKeyConfig, null);
	}
	
	public Map<String, RouterKeyConfig> getRouterKeyConfigs() {
		return this.routerKeyConfigs;
	}
	
	@Override
	@CacheEvict(value = DefaultRouterKeySupport.CACHE_NAME, allEntries = true)
	public void reload() {
	}
	
	public void setDefaultRouterKeyConfig(final RouterKeyConfig defaultRouterKeyConfig) {
		this.defaultRouterKeyConfig = defaultRouterKeyConfig;
	}
	
	@Override
	@CachePut(value = DefaultRouterKeySupport.CACHE_NAME, key = "#key")
	public String setGroupId(String key, String groupId) {
		return groupId;
	}
	
	public void setRouterKeyConfigs(final Map<String, RouterKeyConfig> routerKeyConfigs) {
		this.routerKeyConfigs = routerKeyConfigs;
	}
}
